<script setup>
import {ref, inject} from "vue";
// import { lyla } from "@lylajs/web";
import {fileUpload, useLinearRegression} from "@/res/api/model_api.js";
import learnCommunal from "@/components/communal/learn-communal.vue";
import {
  ArchiveOutline as ArchiveIcon,
  TrashOutline as deleteIcon,
  CreateOutline as updateIcon,
  ArrowBackCircleOutline as backIcon,
} from "@vicons/ionicons5";
import * as echarts from "echarts";
import ModelPredictionBarChart from "@/components/chart/model-prediction-bar-chart.vue";
import router from "@/router/index.js";
const {toPage} = inject('toPage')
//参数设置
const parameterRef =ref(null)
const modelUtilDTO = ref({
  featureColumns: "OverallQual,GrLivArea,TotalBsmtSF,GarageCars,GarageArea,YearBuilt,BedroomAbvGr,LotArea,Fireplaces",
  featureColumn: "SalePrice",
  testSizeUser: 0.3,
  randomStateUser: 42
})
const paramRules = ref({
  testSizeUser:{
    required:false,
    validator(rule, value){
      if(value<0 || value>1){
        return new Error("请输入0-1之间的任意数")
      }
    },
    trigger: ['input','blur']
  },
  randomStateUser: {
    required:false,
    validator(rule, value){
      if(value<0){
        return new Error("请输入一个非负数")
      }
    },
    trigger: ['input','blur']
  }
})

const value = ref(10);
//文件上传相关操作
const token = sessionStorage.getItem('Authorization')
if(!token){
  $message.destroyAll()
  $message.warning("用户token不存在/已失效")
  toPage()
}
const customRequest = ({
                         file,
                         data,
                         headers,
                         withCredentials,
                         action,
                         onFinish,
                         onError,
                         onProgress
                       })=>{
  const formData = new FormData();
  if (data) {
    Object.keys(data).forEach((key) => {
      formData.append(
          key,
          data[key]
      );
    });
  }
  formData.append(file.name, file.file, data.fileType);
  fileUpload({
    fileName: file.name,
    modelType: 1,
    fileType: data.fileType,
    file: file.file
  }).then((res)=>{
    $message.success(res);
    onFinish();
  }).catch((error)=>{
    $message.success(error.message);
    onError();
  })
}

// 进行模型预测使用
let showOption = ref(false)
function modelRun(e){
  $message.info("预测成功")
  showOption.value = true
}
async function predict(){
  $message.info("预测成功")
  showOption.value = true
  const res = await useLinearRegression({
    featureColumns: modelUtilDTO.value.featureColumns,
    featureColumn: modelUtilDTO.value.featureColumn,
    testSizeUser: modelUtilDTO.value.testSizeUser,
    randomStateUser: modelUtilDTO.value.randomStateUser
  })
  // 预测结果
  try {
    console.log(res)
  } catch (error) {
    $message.error("模型使用出错"+error.message)
  }
}

//  模型训练结果数据展示 -- 假数据展示
let optionLegend = ref(['null'])
let optionData = ref([])
let optionSeriesName = ref('null')
let optionSeriesData =  ref([])

let optionData_bar = ref([])
let optionSeriesName_bar = ref('null')
let optionSeriesData_bar = ref([])
watch(showOption, (newVal, oldVal) =>{
  console.log(newVal)
  if (newVal){
    // 折线图
    optionLegend.value = ['price']
    optionData.value = [1915, 1931, 1939, 1973, 1976, 1993, 2000,2001, 2003, 2004]
    optionSeriesName.value = 'price'
    optionSeriesData.value = [208500,181500,223500,140000,250000,143000,118000,200000,129900,307000]

    // 柱状图
    optionData_bar.value = ['MSE','R^2']
    optionSeriesName_bar.value = '评估'
    optionSeriesData_bar.value = [0.32, 0.78]
  }
})

// 返回
function back(){
  router.back()
}
</script>

<template>
  <learn-communal action-key="model">
    <h2>模型预测</h2>
    <!--      左右分割-->
    <n-flex justify="space-between">
<!--      上下分割-->
      <n-flex vertical class="select-model">
        <n-flex justify="space-around">
<!--          左右分割-->
          <n-space vertical style="width: 80%">
            <n-space justify="space-between">
              <n-upload
                  directory-dnd
                  :custom-request="customRequest"
                  :data="{'fileType':'train'}"
                  :max="1"
                  :show-cancel-button="true"
              >
                <n-upload-dragger>
                  <div style="margin-bottom: 12px">
                    <n-icon size="48" :depth="3">
                      <archive-icon />
                    </n-icon>
                  </div>
                  <n-text style="font-size: 16px">
                    点击或者拖动文件到该区域来上传
                  </n-text>
                  <n-p depth="3" style="margin: 8px 0 0 0">
                    训练集上传
                  </n-p>
                </n-upload-dragger>
              </n-upload>
<!--              测试集-->
              <n-upload
                  directory-dnd
                  :custom-request="customRequest"
                  :data="{'fileType':'test'}"
                  :max="1"
                  :show-cancel-button="true"
              >
                <n-upload-dragger>
                  <div style="margin-bottom: 12px">
                    <n-icon size="48" :depth="3">
                      <archive-icon />
                    </n-icon>
                  </div>
                  <n-text style="font-size: 16px">
                    点击或者拖动文件到该区域来上传
                  </n-text>
                  <n-p depth="3" style="margin: 8px 0 0 0">
                    测试集上传
                  </n-p>
                </n-upload-dragger>
              </n-upload>
            </n-space>
            <n-space justify="space-between">
              <n-button type="info">数据预处理</n-button>
              <n-space>
                <n-icon size="24" :component="backIcon" title="返回" class="hover-pointer icon-show" @click="back"/>
                <n-icon size="24" :component="deleteIcon" title="删除" class="hover-pointer icon-show"/>
                <n-icon size="24" title="更改" class="hover-pointer icon-show"><updateIcon/></n-icon>
              </n-space>
            </n-space>
          </n-space >
        </n-flex>

        <n-divider/>
        <n-h2>模型训练结果可视化</n-h2>
        <n-space justify="space-between" v-if="showOption">
          <n-card>
            <model-prediction-line-chart
                :option-legend="optionLegend"
                :option-data="optionData"
                :option-series-name="optionSeriesName"
                :option-series-data="optionSeriesData"/>
          </n-card>
          <n-card>
            <model-prediction-bar-chart
                :option-data="optionData_bar"
                :option-series-name="optionSeriesName_bar"
                :option-series-data="optionSeriesData_bar"/>
          </n-card>
        </n-space>
      </n-flex>
      <!-- 参数调整 -->
      <n-flex vertical class="tuning-parameters">
        <n-h2>参数调参</n-h2>
        <n-space vertical>
          <n-card size="small">
            <n-form
                ref="parameterRef"
                :rules="paramRules"
                :model="modelUtilDTO"
                label-align="right"
                label-placement="left"
                :label-width="96"
            >
              <n-form-item label="特征列表" path="featureColumns">
                <n-input type="textarea" v-model:value="modelUtilDTO.featureColumns" placeholder="['面积']/['area']"/>
              </n-form-item>
              <n-form-item label="目标特征" path="featureColumn">
                <n-input type="text" v-model:value="modelUtilDTO.featureColumn" placeholder="['价格']/['price']"/>
              </n-form-item>
              <n-form-item label="测试集大小" path="testSizeUser">
                <n-input type="text" v-model:value="modelUtilDTO.testSizeUser" placeholder="0.3"/>
              </n-form-item>
              <n-form-item label="数据随机程度" path="randomStateUser">
                <n-input type="text" v-model:value="modelUtilDTO.randomStateUser" placeholder="42"/>
              </n-form-item>
            </n-form>
          </n-card>
        </n-space>
        <n-space justify="end">
          <n-button type="info" @click="predict()">运行模型</n-button>
        </n-space>
      </n-flex>
    </n-flex>
  </learn-communal>
</template>

<style lang="scss" scoped>
#MyEcharts{
  width: 20rem;
  height: 20rem
}
.select-model{
  width: 72%;
}
.tuning-parameters{
  width: 24%;
  box-sizing: border-box;
  border-left: 1px solid #000;
  padding-left: 2.1rem;
}
</style>
